package com.cskaoyan.javase.oop1._6this;

/**
 * this关键字
 * 学习完对象与类后，做以下练习：
 * 创建一个汽车类
 * 有颜色（color）和速度（speed）两个属性，行为是可以跑（run）。
 *
 *
 * 在run成员方法的形参列表中，添加一个局部变量speed，这时,调用run方法,需要传入一个实参速度
 * 如果直接在方法体中访问speed,由于"就近原则"
 * 方法体中访问的speed是形参局部变量的speed
 * 方法调用时,传入的速度是多少,打印的速度就是多少
 *
 * 思考:
 * 如果在这种情况下,我还是想要访问同名的成员变量speed,那么怎么办呢?
 * 需要使用this关键字
 *
 * this关键字:
 * 在Java类中的每一个成员方法中,成员方法的形参列表中
 * 都隐含了一个传参
 * 隐含传入了当前对象
 * 这个当前对象用this关键字指向
 *
 * this指向当前对象,那么什么是当前对象呢?
 * 成员方法最终需要创建对象去调用它
 * 那么谁来调用成员方法,谁就是当前对象!!
 * this其实就是一个引用,可以直接输出它,打印地址值!
 *
 * this关键字的作用:
 *      1.之所以在成员方法中,能够无条件的直接访问本类中的其他成员,原因就是成员方法的形参列表中隐含了this
 *      指向当前对象
 *      所以成员方法的形参中是有对象的
 *      当然一般情况下,隐含的this不需要写出来
 *      直接访问成员即可
 *
 *      2.但是当出现成员变量和局部变量同名时
 *      这时如果省略this
 *      由于"就近原则"会优先访问局部变量
 *      这时如果还想要访问同名的成员变量
 *      需要使用"this."语法
 *      用来区分同名的成员变量和局部变量,这是this关键字最重要的用途之一.
 *
 *      3.在成员方法中只要使用 "this."访问 一个变量
 *      那么该变量一定是成员变量。
 *      在代码比较复杂的情况下，可以显著增加代码可读性。(仅做了解,不要求必须这么做)
 *
 *
 *      引申:
 *      为什么static方法不能直接访问成员变量和成员方法呢?
 *      之所以在成员方法中,能够无条件的直接访问本类中的其他成员,
 *      原因就是成员方法的形参列表中隐含了this,成员方法是存在对象的,所以可以直接访问
 *      但是static方法中没有隐含this传参,没有自身类对象
 *      既然没有对象,就无法直接访问成员变量和成员方法
 *      当然虽然不能直接访问,但是可以间接访问,可以在static方法中手动创建对象,然后去访问(这种访问在同类下一定可以成功)
 *
 *
 *
 *
 * @since 17:08
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        /*Car c = new Car();
        c.speed = 120;
        c.run();*/

        Car c2 = new Car();
        c2.speed = 300;
        /*
            c2对象来调用run方法
            c2对象对于run方法当中的this来说,就是
            当前对象
            run方法当中的this就指向c2对象
         */
        c2.run(200);
        System.out.println(c2);

        Car c3 = new Car();
        c3.run(100);


    }
}

class Car {
    String color;
    // 显式赋值,是在创建对象过程中给成员变量赋值
    double speed = 100;

    public void run(double speed) {
        System.out.println(this);
        test();
        System.out.println(color);
        System.out.println("小汽车以" + this.speed + "公里每小时的速度,嘟嘟嘟的在马路上跑!");
    }

    public void test(){
    }

    public static void testStatic(){
        // System.out.println(color);
        Car c = new Car();
        System.out.println(c.color);
    }
}